package com.dreamer.service.mobile.impl;

import com.dreamer.domain.mall.goods.GoodsType;
import com.dreamer.domain.pmall.goods.GoodsStandard;
import com.dreamer.domain.pmall.goods.PmallGoods;
import com.dreamer.domain.pmall.goods.PmallGoodsType;
import com.dreamer.domain.pmall.order.*;
import com.dreamer.domain.pmall.shopcart.ShopCart;
import com.dreamer.domain.pyramid.ParamConfig;
import com.dreamer.domain.pyramid.Pyramid;
import com.dreamer.domain.pyramid.PyramidUser;
import com.dreamer.domain.user.*;
import com.dreamer.domain.user.enums.AccountsType;
import com.dreamer.domain.wechat.WxConfig;
import com.dreamer.repository.mobile.OrderDao;
import com.dreamer.repository.mobile.OrderItemDao;
import com.dreamer.repository.mobile.UserDao;
import com.dreamer.repository.pyramid.PyramidDAO;
import com.dreamer.repository.pyramid.PyramidUserDAO;
import com.dreamer.repository.user.AccountsDAO;
import com.dreamer.repository.user.UserDAO;
import com.dreamer.service.mobile.*;
import com.dreamer.service.mobile.factory.WxConfigFactory;
import com.dreamer.service.pyramid.ParamConfigHandler;
import com.dreamer.service.pyramid.PyramidHandler;
import com.dreamer.service.pyramid.PyramidUserHandler;
import com.dreamer.util.CommonUtil;
import com.dreamer.util.PreciseComputeUtil;
import com.fasterxml.jackson.databind.annotation.JsonAppend;
import com.wxjssdk.JSAPI;
import com.wxjssdk.dto.SdkResult;
import com.wxjssdk.util.XmlUtil;
import net.sf.json.JSONObject;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ps.mx.otter.exception.ApplicationException;
import ps.mx.otter.utils.SearchParameter;

import java.util.*;

/**
 * Created by huangfei on 11/07/2017.
 */
@Service
public class OrderHandlerImpl extends BaseHandlerImpl<Order> implements OrderHandler {

    @Autowired
    private PyramidHandler pyramidHandler;

    @Autowired
    private PyramidUserHandler pyramidUserHandler;

    @Autowired
    private PyramidUserDAO pyramidUserDAO;

    @Autowired
    private PyramidDAO pyramidDAO;

    @Autowired
    private AccountsDAO accountsDAO;

    @Override
    public List<Order> findOrderByUserId(Integer userId) {
        return orderDao.findOrderByUserId(userId);
    }

    @Override
    public List<Order> findOrderByUserIds(Integer userId) {
        return orderDao.findOrderByUserIds(userId);
    }

    @Override
    @Transactional
    public Order commitOrder(Agent agent, AddressClone addressClone, ShopCart shopCart, String remark) {
        Order order = new Order(agent, addressClone, remark);
        Set<OrderItem> items = bulidItems(order, shopCart);
        order.setItems(items);
        order.setAmount(PreciseComputeUtil.round(shopCart.getAmount()));
        order.setQuantity(shopCart.getQuantity());
        //提交订单
        commitOrder(order);
        //保存订单
        order = save(order);
        return order;
    }


    //生成payOpenid  并且去支付
    @Override
    @Transactional
    public String resetOpenIdToPay(String code, String orderId) {
        Order order = get(Integer.valueOf(orderId));
        if (order == null) {
            LOG.error("获取order为空,{}", orderId);
            throw new ApplicationException("订单不存在！请联系管理员！");
        }
        Agent agent = agentHandler.get(order.getUser().getId());
        WxConfig wxConfig = wxConfigFactory.getPayConfig();
        SdkResult sdkResult = JSAPI.getTokenAndOpenId(wxConfig.getAppid(), wxConfig.getSecret(), code);
        if (sdkResult.isSuccess()) {//获取openId成功了  就去支付
            JSONObject jsonObject = (JSONObject) sdkResult.getData();
            try {
                if (agent.getPayOpenid() == null || !agent.getPayOpenid().equals(jsonObject.getString("openid"))) {
                    agent.setPayOpenid(jsonObject.getString("openid"));
                    agentHandler.merge(agent);
                }
            } catch (Exception e) {
                System.out.println("异常:" + e.getMessage());
            }
            String jsApiParam = payHandler.toWxPay(wxConfig, agent.getPayOpenid(), order.getOrderNo(), order.getAmount(),WxConfig.PMALL_NOTICE_URL);
            return jsApiParam;
        } else {
            LOG.error("获取payOpenid失败:{}", sdkResult.getError());
            throw new ApplicationException("获取获取payOpenid失败失败ERROR:" + sdkResult.getError());
        }
    }

    //支付
    @Transactional
    private void payOrder(Integer id, PaymentWay paymentWay) {
        Order order = get(id);
        //支付状态
        payOrder(order, paymentWay);
        //减库存
        deductMallGoodsAccount(order);
        //增加消费
        AccountsRecord accountsRecord = accountsHandler.increaseAccountAndRecord(AccountsType.CONSUME,order.getUser(),order.getUser(),order.getAmount(),"累积-优惠商城购物累积消费值");
        //获得奖励
        List<AccountsRecord> records = rewardVoucher(order);
        //保存获得奖励记录
        accountsRecordHandler.saveList(records);
        //累积消费记录
        accountsRecordHandler.save(accountsRecord);
        //通知获得奖励
        noticeHandler.noticeAccountRecords(records);
        //保存
        merge(order);
    }

    //支付 //接受微信支付回调 并支付  返回支付结果
    @Override
    @Transactional
    public String payOrderByWx(String body) {
        Map<String, String> xml = XmlUtil.xmlToMap(body);
        String out_trade_no = xml.get("out_trade_no");
        Order order = get("orderNo", out_trade_no);
        try {
            payOrder(order.getId(), PaymentWay.WX);//微信支付
        } catch (Exception e) {
            LOG.error("微信支付回调支付异常,{}", e.getMessage());
            LOG.error("订单id,{}", order.getId());
            payOrderWithError(order.getId(), PaymentWay.WX);
        }
        //返回支付结果
        Map<String, Object> map = new HashMap();
        map.put("return_code", "SUCCESS");
        map.put("return_msg", "OK");
        String result = XmlUtil.mapToXml(map);
        return result;
    }


    //管理员支付
    @Override
    @Transactional
    public void payOrderByAdmin(Integer id) {
        payOrder(id, PaymentWay.ADMIN);
    }


    private void delivery(Order order) {
        //设置状态
        order.setStatus(OrderStatus.SHIPPED);
        order.setShippingTime(new Date());
    }

    @Transactional
    private void payOrderWithError(Integer id, PaymentWay paymentWay) {
        Order order = get(id);
//        payOrder(order, paymentWay);
        order.setPaymentWay(paymentWay);
        order.setPaymentStatus(PaymentStatus.PAIDERROR);
        order.setPaymentTime(new Date());
        merge(order);
    }

    private void payOrder(Order order, PaymentWay paymentWay) {
        if (order == null) {
            logger.error("订单不存在id:{}", order.getId());
            throw new ApplicationException("订单不存在!id:" + order.getId());
        }
        if (hasPaid(order)) {
            logger.error("订单已经支付!");
            throw new ApplicationException("订单已经支付!id:" + order.getId());

        }
        order.setPaymentStatus(PaymentStatus.PAID);//设置已经支付
        order.setPaymentTime(new Date());
        order.setPaymentWay(paymentWay);
    }

    //扣减账户
    private AccountsRecord deductAccounts(Order order, AccountsType accountsType) {
        if (accountsType == AccountsType.ADVANCE) {//置换券支付只能支付置换券类型的
            if (!order.getCanAdvance()) {
                throw new ApplicationException("包含不能置换券支付的产品!");
            }
        }
        String more = "购物-优惠商城购物支付";
        AccountsRecord accountsRecord = accountsHandler.deductAccountAndRecord(accountsType, order.getUser(), order.getUser(), order.getAmount(), more);
        return accountsRecord;
    }


    //是否已经支付
    private boolean hasPaid(Order order) {
        if (order.getPaymentStatus() == PaymentStatus.UNPAID) {
            return false;
        }
        return true;
    }

    //是否已经发货
    private boolean hasDelivery(Order order) {
        if (order.getStatus().equals(OrderStatus.NEW)) {
            return false;
        }
//        System.out.println(order.getLogistics()==null);
        return true;
    }

    @Autowired
    private ParamConfigHandler paramConfigHandler;

    /**
     * 商城购买商品，代金券支付
     * @param id
     * @param payOrderByAccounts
     */
    @Override
    @Transactional
    public void payOrderByAccounts(Integer id, Integer payOrderByAccounts) {

        Order order = get(id);

        AccountsType accountsType = AccountsType.stateOf(payOrderByAccounts);

        //TODO 保存套餐
        List<PmallGoods> pmallGoodsList = new ArrayList<>();

        //TODO 获取当前订单 ------判断当前订单是不是套餐订单
        Set<OrderItem> orderItemSet = order.getItems();
        if(orderItemSet != null){
            for(OrderItem orderItem : orderItemSet){
                PmallGoods pmallGoods = orderItem.getPmallGoods();
                if(pmallGoods != null){
                    PmallGoodsType pmallGoodsType = pmallGoods.getGoodsType();
                    if(pmallGoodsType != null){
                        if(pmallGoodsType.getId()==15 || pmallGoodsType.getName().equals("代理套餐")){
                            pmallGoodsList.add(pmallGoods);
                            order.setSign("代理套餐");
                            //TODO 标记代理
                            Agent agent = agentHandler.get(order.getUser().getId());
                            if(!agent.getSign().equals("代理")){
                                agent.setSign("代理");
                                agentHandler.merge(agent);
                            }
                        }
                    }
                }
            }
        }  //TODO 任何一个为空就结束

        if(pmallGoodsList.size() > 0 && accountsType.getState() != 0 && accountsType.getState() != 4){
            throw new ApplicationException("代理套餐只能使用现金钱包和奖金钱包进行支付购买！");
        }

        //TODO 保存代理专享
        List<PmallGoods> pgList = new ArrayList<>();

        //TODO 获取当前订单 ------判断当前订单是不是代理专享订单
        Set<OrderItem> ios = order.getItems();
        if(ios != null){
            for(OrderItem oi : ios){
                PmallGoods pg = oi.getPmallGoods();
                if(pg != null){
                    PmallGoodsType pgt = pg.getGoodsType();
                    if(pgt != null){
                        if(pgt.getId()==24 || pgt.getName().equals("代理专享")){
                            pgList.add(pg);
                        }
                    }
                }
            }
        }  //TODO 任何一个为空就结束

        if(pgList.size() > 0 && accountsType.getState() != 0){
            throw new ApplicationException("代理专享只能使用现金钱包进行支付购买！");
        }

        //TODO 减少库存
        deductMallGoodsAccount(order);
        PaymentWay paymentWay;
        //TODO 设置为支付状态
        if (accountsType == AccountsType.ShopVoucher) { //购物券
            paymentWay = PaymentWay.ShopVouchers;
        } else if(accountsType == AccountsType.VOUCHER) { //代金券
            paymentWay = PaymentWay.VOUCHER;
        }else{
            paymentWay = PaymentWay.MyBonus;
        }
        List<AccountsRecord> records = new ArrayList<>();
        //TODO 减少代金券
        records.add(deductAccounts(order, accountsType));
        //TODO 支付状态
        payOrder(order, paymentWay);
        //TODO 保存
        order.setIsUse("否");
        merge(order);
        //TODO 保存代金券记录
        accountsRecordHandler.saveList(records);

        //TODO 当前用户
        Integer currUserId = order.getUser().getId();

        //TODO 判断是第几轮
        Agent agent = agentHandler.get(currUserId);
        Integer count = 0;
        if(agent.getFrequency().equals("1")){
            List<Agent> agentList = agentHandler.findChildrens(currUserId);
            for(int i = 0; i < agentList.size(); i++){
                Agent agent1 = agentList.get(0);
                List<PyramidUser> puList = pyramidUserDAO.findPyramidUserByUserId(agent1.getId());
                if(puList.size() > 0){
                    count++;
                }
            }
            if(count < 2){
                throw new ApplicationException("您需要推荐两个代理(1980)后才可以再一次进入网体!");
            }
        }

        //TODO 支付成功后：----------------------------->>>>>>

        //TODO 本次消费的代金券
        Double oAmount = order.getAmount();

        //TODO 获取参数配置
        List<ParamConfig> paramConfigs = paramConfigHandler.findAll();
        int countSort1=0;
        for(ParamConfig p : paramConfigs){
            if(p.getSort()==1){
                countSort1 += p.getNumberBoxes();
            }
        }
        int countSort2=0;
        for(ParamConfig p : paramConfigs){
            if(p.getSort()==1 || p.getSort()==2){
                countSort2 += p.getNumberBoxes();
            }
        }

        //TODO 判断当前用户是否存在PyramidUser里面：
        List<PyramidUser> is_be_PU = pyramidUserDAO.findPyramidUserByUserId(currUserId);
        if(is_be_PU.size() == 0){

            //TODO 不存在PU --------------->>>>>以下是处理不存在PU

            //TODO 是套餐
            if(pmallGoodsList.size() > 0 && pmallGoodsList != null && order.getQuantity() >= 1){

                //TODO 满足6盒可以进入金字塔
                if(order.getQuantity() * countSort1 >= countSort1){

                    int indexSort = 1;

                    //TODO 返代金券
                    VoucherProfit(currUserId,oAmount);

                    //TODO 处理第一关卡第一层
                    Pyramid P1 = pyramidDAO.findBySort(indexSort);
                    if(P1 != null){
                        //TODO 新用户：从 1-1-0 开始 加入金字塔  0为虚拟数字  ------> 开始挤人  每层都需要判断
                        PyramidUser addPU = new PyramidUser();
                        //addPU.setPyramidId(P1.getId()); //第一关第一层
                        addPU.setPyramid(P1);
                        //addPU.setUserId(currUserId); //当前用户
                        addPU.setUser(order.getUser());
                        addPU.setPosition("0");  //第一个位置
                        addPU.setCreateTime(new Date()); //创建时间
                        pyramidUserHandler.saveOrupdate(addPU);
                        //TODO 获取当前层的人数
                        List<PyramidUser> PUList1 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P1.getId());
                        Integer puNumber1 = PUList1.size();
                        //TODO 判断PU中人数是否大于当前层限制人数
                        if(puNumber1 <= P1.getPeopleNumber()){
                            //TODO 循环修改位置，每个都+1
                            updatePUPosition(PUList1);
                        }else{
                            //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户 4.在修改其他人的位置
                            updatePUPositionAndBonusAndRecord(P1);

                            //TODO 处理第一关卡第二层
                            Pyramid P2 = pyramidDAO.findBySort(indexSort+1);
                            if(P2 != null){
                                //TODO 获取当前层的人数
                                List<PyramidUser> PUList2 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P2.getId());
                                Integer puNumber2 = PUList2.size();
                                //TODO 判断PU中人数是否大于当前层限制人数
                                if(puNumber2 <= P2.getPeopleNumber()){
                                    //TODO 循环修改位置，每个都+1
                                    updatePUPosition(PUList2);
                                }else{
                                    //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                    updatePUPositionAndBonusAndRecord(P2);


                                    //TODO 处理第一关卡第三层
                                    Pyramid P3 = pyramidDAO.findBySort(indexSort+2);
                                    if(P3 != null){
                                        //TODO 获取当前层的人数
                                        List<PyramidUser> PUList3 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P3.getId());
                                        Integer puNumber3 = PUList3.size();
                                        //TODO 判断PU中人数是否大于当前层限制人数
                                        if(puNumber3 <= P3.getPeopleNumber()){
                                            //TODO 循环修改位置，每个都+1
                                            updatePUPosition(PUList3);
                                        }else{
                                            //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                            updatePUPositionAndBonusAndRecord(P3);

                                            //TODO 处理第一关卡第四层
                                            Pyramid P4 = pyramidDAO.findBySort(indexSort+3);
                                            if(P4 != null){
                                                //TODO 获取当前层的人数
                                                List<PyramidUser> PUList4 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P4.getId());
                                                Integer puNumber4 = PUList4.size();
                                                //TODO 判断PU中人数是否大于当前层限制人数
                                                if(puNumber4 <= P4.getPeopleNumber()){
                                                    //TODO 循环修改位置，每个都+1
                                                    updatePUPosition(PUList4);
                                                }else{
                                                    //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                    updatePUPositionAndBonusAndRecord(P4);

                                                    //TODO 处理第一关卡第五层
                                                    Pyramid P5 = pyramidDAO.findBySort(indexSort+4);
                                                    if(P5 != null){
                                                        //TODO 获取当前层的人数
                                                        List<PyramidUser> PUList5 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P5.getId());
                                                        Integer puNumber5 = PUList5.size();
                                                        //TODO 判断PU中人数是否大于当前层限制人数
                                                        if(puNumber5 <= P5.getPeopleNumber()){
                                                            //TODO 循环修改位置，每个都+1
                                                            updatePUPosition(PUList5);
                                                        }else{
                                                            //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                            updatePUPositionAndBonusAndRecord(P5);

                                                            //TODO 处理第一关卡第六层
                                                            Pyramid P6 = pyramidDAO.findBySort(indexSort+5);
                                                            if(P6 != null){
                                                                //TODO 获取当前层的人数
                                                                List<PyramidUser> PUList6 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P6.getId());
                                                                Integer puNumber6 = PUList6.size();
                                                                //TODO 判断PU中人数是否大于当前层限制人数
                                                                if(puNumber6 <= P6.getPeopleNumber()){
                                                                    //TODO 循环修改位置，每个都+1
                                                                    updatePUPosition(PUList6);
                                                                }else{
                                                                    //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                    updatePUPositionAndBonusAndRecord(P6);

                                                                    //TODO 处理第一关卡第七层
                                                                    Pyramid P7 = pyramidDAO.findBySort(indexSort+6);
                                                                    if(P7 != null){
                                                                        //TODO 获取当前层的人数
                                                                        List<PyramidUser> PUList7 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P7.getId());
                                                                        Integer puNumber7 = PUList7.size();
                                                                        //TODO 判断PU中人数是否大于当前层限制人数
                                                                        if(puNumber7 <= P7.getPeopleNumber()){
                                                                            //TODO 循环修改位置，每个都+1
                                                                            updatePUPosition(PUList7);
                                                                        }else{
                                                                            //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                            updatePUPositionAndBonusAndRecord(P7);

                                                                            //TODO 处理第一关卡第八层
                                                                            Pyramid P8 = pyramidDAO.findBySort(indexSort+7);
                                                                            if(P8 != null){
                                                                                //TODO 获取当前层的人数
                                                                                List<PyramidUser> PUList8 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P8.getId());
                                                                                Integer puNumber8 = PUList8.size();
                                                                                //TODO 判断PU中人数是否大于当前层限制人数
                                                                                if(puNumber8 <= P8.getPeopleNumber()){
                                                                                    //TODO 循环修改位置，每个都+1
                                                                                    updatePUPosition(PUList8);
                                                                                }else{
                                                                                    //TODO 获取当前层最后的这个用户并修改位置
                                                                                    PyramidUser PU8 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionASCLast(P8.getId());
                                                                                    //TODO 获取盒数看有没有资格直接跳入9层
                                                                                    //List<Order> orderList = orderDao.findOrderByUserIdAndSign(PU8.getUserId());
                                                                                    List<Order> orderList = orderDao.findOrderByUserIdAndSign(PU8.getUser().getId());
                                                                                    Integer currCount1 = 0;
                                                                                    if(orderList != null) {
                                                                                        for (Order o : orderList) {
                                                                                            currCount1 += o.getQuantity();
                                                                                        }
                                                                                    }
                                                                                    if(currCount1 * 6 < countSort2){
                                                                                        //TODO 进入待跳区
                                                                                        Pyramid pyramid = pyramidHandler.findById(16);
                                                                                        //PU8.setPyramidId(16);  //待跳区
                                                                                        PU8.setPyramid(pyramid);
                                                                                        //PU8.setUserId(PU8.getUserId()); //当前用户
                                                                                        PU8.setUser(PU8.getUser());
                                                                                        int a = (int)(Math.random()*(9999-1000+1))+1000;
                                                                                        PU8.setPosition(String.valueOf(a));  //随便给个位置
                                                                                        PU8.setUpdateTime(new Date()); //修改时间
                                                                                        pyramidUserHandler.saveOrupdate(PU8);

                                                                                        //TODO 当前层原来有的用户位置依次+1
                                                                                        //TODO 获取当前层的人数
                                                                                        List<PyramidUser> PUList8_1 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P8.getId());
                                                                                        //Integer puNumber8_1 = PUList8_1.size();
                                                                                        //TODO 判断PU中人数是否大于当前层限制人数
                                                                                        //int indexSize = puNumber8_1;
                                                                                        //if(indexSize >= 1){
                                                                                            //TODO 循环修改位置，每个都+1
                                                                                            for (int j = 0; j < PUList8_1.size(); j++) {
                                                                                                PyramidUser updatePU8 = PUList8_1.get(j);
                                                                                                String position = updatePU8.getPosition();
                                                                                                Integer index = Integer.valueOf(position) + 1;
                                                                                                updatePU8.setPosition(String.valueOf(index));
                                                                                                pyramidUserHandler.saveOrupdate(updatePU8);
                                                                                            }
                                                                                        //}
                                                                                    }else{
                                                                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                        updatePUPositionAndBonusAndRecord(P8);

                                                                                        //TODO 处理第二关卡第九层
                                                                                        Pyramid P9 = pyramidDAO.findBySort(indexSort+8);
                                                                                        if(P9 != null) {
                                                                                            //TODO 获取当前层的人数
                                                                                            List<PyramidUser> PUList9 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P9.getId());
                                                                                            Integer puNumber9 = PUList9.size();
                                                                                            //TODO 判断PU中人数是否大于当前层限制人数
                                                                                            if (puNumber9 <= P9.getPeopleNumber()) {
                                                                                                //TODO 循环修改位置，每个都+1
                                                                                                updatePUPosition(PUList9);
                                                                                            }else{
                                                                                                //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                                updatePUPositionAndBonusAndRecord(P9);

                                                                                                //TODO 处理第二关卡第十层
                                                                                                Pyramid P10 = pyramidDAO.findBySort(indexSort+9);
                                                                                                if(P10 != null) {
                                                                                                    //TODO 获取当前层的人数
                                                                                                    List<PyramidUser> PUList10 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P10.getId());
                                                                                                    Integer puNumber10 = PUList10.size();
                                                                                                    //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                    if (puNumber10 <= P10.getPeopleNumber()) {
                                                                                                        //TODO 循环修改位置，每个都+1
                                                                                                        updatePUPosition(PUList10);
                                                                                                    }else{
                                                                                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                                        updatePUPositionAndBonusAndRecord(P10);


                                                                                                        //TODO 处理第二关卡第十一层
                                                                                                        Pyramid P11 = pyramidDAO.findBySort(indexSort+10);
                                                                                                        if(P11 != null) {
                                                                                                            //TODO 获取当前层的人数
                                                                                                            List<PyramidUser> PUList11 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P11.getId());
                                                                                                            Integer puNumber11 = PUList11.size();
                                                                                                            //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                            if (puNumber11 <= P11.getPeopleNumber()) {
                                                                                                                //TODO 循环修改位置，每个都+1
                                                                                                                updatePUPosition(PUList11);
                                                                                                            }else{
                                                                                                                //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                                                updatePUPositionAndBonusAndRecord(P11);


                                                                                                                //TODO 处理第二关卡第十二层
                                                                                                                Pyramid P12 = pyramidDAO.findBySort(indexSort+11);
                                                                                                                if(P12 != null) {
                                                                                                                    //TODO 获取当前层的人数
                                                                                                                    List<PyramidUser> PUList12 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P12.getId());
                                                                                                                    Integer puNumber12 = PUList12.size();
                                                                                                                    //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                                    if (puNumber12 <= P12.getPeopleNumber()) {
                                                                                                                        //TODO 循环修改位置，每个都+1
                                                                                                                        updatePUPosition(PUList12);
                                                                                                                    }else{
                                                                                                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                                                        updatePUPositionAndBonusAndRecord(P12);


                                                                                                                        //TODO 处理第二关卡第十三层
                                                                                                                        Pyramid P13 = pyramidDAO.findBySort(indexSort+12);
                                                                                                                        if(P13 != null) {
                                                                                                                            //TODO 获取当前层的人数
                                                                                                                            List<PyramidUser> PUList13 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P13.getId());
                                                                                                                            Integer puNumber13 = PUList13.size();
                                                                                                                            //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                                            if (puNumber13 <= P13.getPeopleNumber()) {
                                                                                                                                //TODO 循环修改位置，每个都+1
                                                                                                                                updatePUPosition(PUList13);
                                                                                                                            }else{
                                                                                                                                //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                                                                updatePUPositionAndBonusAndRecord(P13);


                                                                                                                                //TODO 处理第二关卡第十四层
                                                                                                                                Pyramid P14 = pyramidDAO.findBySort(indexSort+13);
                                                                                                                                if(P14 != null) {
                                                                                                                                    //TODO 获取当前层的人数
                                                                                                                                    List<PyramidUser> PUList14 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P14.getId());
                                                                                                                                    Integer puNumber14 = PUList14.size();
                                                                                                                                    //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                                                    if (puNumber14 <= P14.getPeopleNumber()) {
                                                                                                                                        //TODO 循环修改位置，每个都+1
                                                                                                                                        updatePUPosition(PUList14);
                                                                                                                                    }else{
                                                                                                                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                                                                                        updatePUPositionAndBonusAndRecord(P14);


                                                                                                                                        //TODO 处理第二关卡第十五层
                                                                                                                                        Pyramid P15 = pyramidDAO.findBySort(indexSort+14);
                                                                                                                                        if(P15 != null) {
                                                                                                                                            //TODO 获取当前层的人数
                                                                                                                                            List<PyramidUser> PUList15 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P15.getId());
                                                                                                                                            Integer puNumber15 = PUList15.size();
                                                                                                                                            //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                                                            if (puNumber15 <= P15.getPeopleNumber()) {
                                                                                                                                                //TODO 循环修改位置，每个都+1
                                                                                                                                                updatePUPosition(PUList15);
                                                                                                                                            }else{
                                                                                                                                                //TODO 当前层原来有的用户位置依次+1
                                                                                                                                                //TODO 获取当前层的人数
                                                                                                                                                List<PyramidUser> PUList15_1 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P15.getId());
                                                                                                                                                //Integer puNumber15_1 = PUList15_1.size();
                                                                                                                                                //TODO 判断PU中人数是否大于当前层限制人数
                                                                                                                                                //int indexSize = puNumber15_1 - 1;
                                                                                                                                                //if(indexSize >= 1){
                                                                                                                                                    //TODO 循环修改位置，每个都+1
                                                                                                                                                    for (int j = 0; j < PUList15_1.size(); j++) {
                                                                                                                                                        PyramidUser updatePU15 = PUList15_1.get(j);
                                                                                                                                                        String position = updatePU15.getPosition();
                                                                                                                                                        Integer index = Integer.valueOf(position) + 1;
                                                                                                                                                        updatePU15.setPosition(String.valueOf(index));
                                                                                                                                                        pyramidUserHandler.saveOrupdate(updatePU15);
                                                                                                                                                    }
                                                                                                                                                //}
                                                                                                                                                //TODO 获取当前层最后的这个用户并删除
                                                                                                                                                PyramidUser PU15 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionASCLast(P15.getId());
                                                                                                                                                //TODO 获取当前层的奖金并给到最后这个人
                                                                                                                                                //Accounts currAccounts15 = accountsDAO.findByAgentId(PU15.getUserId());
                                                                                                                                                Accounts currAccounts15 = accountsDAO.findByAgentId(PU15.getUser().getId());
                                                                                                                                                currAccounts15.setMyBonus(currAccounts15.getMyBonus() + P15.getBonus());
                                                                                                                                                accountsDAO.merge(currAccounts15);
                                                                                                                                                //TODO 修改所有订单为已使用
                                                                                                                                                //List<Order> orderList2 = orderDao.findOrderByUserId(PU15.getUserId());
                                                                                                                                                List<Order> orderList2 = orderDao.findOrderByUserId(PU15.getUser().getId());
                                                                                                                                                for(Order order1 : orderList2){
                                                                                                                                                    order1.setIsUse("是");
                                                                                                                                                    orderDao.merge(order1);
                                                                                                                                                }
                                                                                                                                                Agent agent1 = agentHandler.get(PU15.getUser().getId());
                                                                                                                                                agent1.setFrequency("1");
                                                                                                                                                agentHandler.merge(agent1);
                                                                                                                                                //TODO 删除15层最后这个人
                                                                                                                                                pyramidUserHandler.removeActivity(PU15);
                                                                                                                                            }
                                                                                                                                        }else{
                                                                                                                                            System.out.println("结束了!");
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                }else{
                                                                                                                                    System.out.println("结束了!");
                                                                                                                                }
                                                                                                                            }
                                                                                                                        }else{
                                                                                                                            System.out.println("结束了!");
                                                                                                                        }
                                                                                                                    }
                                                                                                                }else{
                                                                                                                    System.out.println("结束了!");
                                                                                                                }
                                                                                                            }
                                                                                                        }else{
                                                                                                            System.out.println("结束了!");
                                                                                                        }
                                                                                                    }
                                                                                                }else{
                                                                                                    System.out.println("结束了!");
                                                                                                }
                                                                                            }
                                                                                        }else{
                                                                                            System.out.println("结束了!");
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }else{
                                                                                System.out.println("结束了!");
                                                                            }
                                                                        }
                                                                    }else{
                                                                        System.out.println("结束了!");
                                                                    }
                                                                }
                                                            }else{
                                                                System.out.println("结束了!");
                                                            }
                                                        }
                                                    }else{
                                                        System.out.println("结束了!");
                                                    }
                                                }
                                            }else{
                                                System.out.println("结束了!");
                                            }
                                        }
                                    }else{
                                        System.out.println("结束了!");
                                    }
                                }
                            }else{
                                System.out.println("结束了!");
                            }
                        }
                    }else{
                        System.out.println("结束了!");
                    }
                }else{
                    System.out.println("结束了!");
                }
            }else{
                //TODO 不是套餐 同时不存在PU  不做任何处理  直接结束
                System.out.println("结束了!");
            }
        }else{
            //TODO 存在PU --------------->>>>>以下是处理存在PU

            //TODO 获取PU的位置
            Integer pyramidId = 0;
            for(PyramidUser pyramidUser : is_be_PU){
                //pyramidId = pyramidUser.getPyramidId();
                pyramidId = pyramidUser.getPyramid().getId();
            }
            //TODO 获取P 的关卡和层数
            Pyramid pyramid = pyramidDAO.findById(pyramidId);
            //TODO 关
            String checkpoint = pyramid.getCheckpoint();
            //TODO 层
            String layerNumber = pyramid.getLayerNumber();

            //TODO 处理待跳区的用户 16层
            if(checkpoint.equals("1-2") && layerNumber.equals("8-9")){

                //TODO 是不是套餐
                if(pmallGoodsList.size() > 0 && pmallGoodsList != null && order.getQuantity() >= 1){
                    if(order.getQuantity() * countSort1 >= countSort1){

                        //TODO 从待跳区进入第二关第九层

                        int indexSort = 1;

                        //TODO 返代金券
                        VoucherProfit(currUserId,oAmount);

                        Pyramid P9 = pyramidDAO.findBySort(indexSort+8);
                        if(P9 != null) {
                            //TODO 修改位置
                            PyramidUser PU9 = pyramidUserDAO.findPyramidUserByUserIdObj(currUserId);
                            //PU9.setPyramidId(P9.getId());
                            //PU9.setUserId(currUserId); //当前用户
                            PU9.setPyramid(P9);
                            PU9.setUser(order.getUser());
                            PU9.setPosition("0");  //第一个位置
                            PU9.setUpdateTime(new Date()); //修改时间
                            pyramidUserHandler.saveOrupdate(PU9);
                            //TODO 获取当前层的人数
                            List<PyramidUser> PUList9 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P9.getId());
                            Integer puNumber9 = PUList9.size();
                            //TODO 判断PU中人数是否大于当前层限制人数
                            if (puNumber9 <= P9.getPeopleNumber()) {
                                //TODO 循环修改位置，每个都+1
                                updatePUPosition(PUList9);
                            }else{
                                //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                updatePUPositionAndBonusAndRecord(P9);

                                //TODO 处理第二关卡第十层
                                Pyramid P10 = pyramidDAO.findBySort(indexSort+9);
                                if(P10 != null) {
                                    //TODO 获取当前层的人数
                                    List<PyramidUser> PUList10 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P10.getId());
                                    Integer puNumber10 = PUList10.size();
                                    //TODO 判断PU中人数是否大于当前层限制人数
                                    if (puNumber10 <= P10.getPeopleNumber()) {
                                        //TODO 循环修改位置，每个都+1
                                        updatePUPosition(PUList10);
                                    } else {
                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                        updatePUPositionAndBonusAndRecord(P10);

                                        //TODO 处理第二关卡第十一层
                                        Pyramid P11 = pyramidDAO.findBySort(indexSort + 10);
                                        if (P11 != null) {
                                            //TODO 获取当前层的人数
                                            List<PyramidUser> PUList11 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P11.getId());
                                            Integer puNumber11 = PUList11.size();
                                            //TODO 判断PU中人数是否大于当前层限制人数
                                            if (puNumber11 <= P11.getPeopleNumber()) {
                                                //TODO 循环修改位置，每个都+1
                                                updatePUPosition(PUList11);
                                            } else {
                                                //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                updatePUPositionAndBonusAndRecord(P11);


                                                //TODO 处理第二关卡第十二层
                                                Pyramid P12 = pyramidDAO.findBySort(indexSort + 11);
                                                if (P12 != null) {
                                                    //TODO 获取当前层的人数
                                                    List<PyramidUser> PUList12 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P12.getId());
                                                    Integer puNumber12 = PUList12.size();
                                                    //TODO 判断PU中人数是否大于当前层限制人数
                                                    if (puNumber12 <= P12.getPeopleNumber()) {
                                                        //TODO 循环修改位置，每个都+1
                                                        updatePUPosition(PUList12);
                                                    } else {
                                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                        updatePUPositionAndBonusAndRecord(P12);


                                                        //TODO 处理第二关卡第十三层
                                                        Pyramid P13 = pyramidDAO.findBySort(indexSort + 12);
                                                        if (P13 != null) {
                                                            //TODO 获取当前层的人数
                                                            List<PyramidUser> PUList13_2 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P13.getId());
                                                            Integer puNumber13 = PUList13_2.size();
                                                            //TODO 判断PU中人数是否大于当前层限制人数
                                                            if (puNumber13 <= P13.getPeopleNumber()) {
                                                                //TODO 循环修改位置，每个都+1
                                                                updatePUPosition(PUList13_2);
                                                            } else {
                                                                //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                updatePUPositionAndBonusAndRecord(P13);


                                                                //TODO 处理第二关卡第十四层
                                                                Pyramid P14 = pyramidDAO.findBySort(indexSort + 13);
                                                                if (P14 != null) {
                                                                    //TODO 获取当前层的人数
                                                                    List<PyramidUser> PUList14_2 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P14.getId());
                                                                    Integer puNumber14 = PUList14_2.size();
                                                                    //TODO 判断PU中人数是否大于当前层限制人数
                                                                    if (puNumber14 <= P14.getPeopleNumber()) {
                                                                        //TODO 循环修改位置，每个都+1
                                                                        updatePUPosition(PUList14_2);
                                                                    } else {
                                                                        //TODO 1.获取当前层最后的这个用户并修改位置 2.获取当前层的奖金并给到最后这个人 3.记录账户
                                                                        updatePUPositionAndBonusAndRecord(P14);


                                                                        //TODO 处理第二关卡第十五层
                                                                        Pyramid P15 = pyramidDAO.findBySort(indexSort + 14);
                                                                        if (P15 != null) {
                                                                            //TODO 获取当前层的人数
                                                                            List<PyramidUser> PUList15 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P15.getId());
                                                                            Integer puNumber15 = PUList15.size();
                                                                            //TODO 判断PU中人数是否大于当前层限制人数
                                                                            if (puNumber15 <= P15.getPeopleNumber()) {
                                                                                //TODO 循环修改位置，每个都+1
                                                                                updatePUPosition(PUList15);
                                                                            } else {
                                                                                //TODO 当前层原来有的用户位置依次+1
                                                                                //TODO 获取当前层的人数
                                                                                List<PyramidUser> PUList15_2 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(P15.getId());
                                                                                //TODO 判断PU中人数是否大于当前层限制人数
                                                                                //TODO 循环修改位置，每个都+1
                                                                                for (int j = 0; j < PUList15_2.size(); j++) {
                                                                                    PyramidUser updatePU15 = PUList15_2.get(j);
                                                                                    String position = updatePU15.getPosition();
                                                                                    Integer index = Integer.valueOf(position) + 1;
                                                                                    updatePU15.setPosition(String.valueOf(index));
                                                                                    pyramidUserHandler.saveOrupdate(updatePU15);
                                                                                }
                                                                                //TODO 获取当前层最后的这个用户并删除
                                                                                PyramidUser PU15 = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionASCLast(P15.getId());
                                                                                //TODO 获取当前层的奖金并给到最后这个人
                                                                                //Accounts currAccounts15 = accountsDAO.findByAgentId(PU15.getUserId());
                                                                                Accounts currAccounts15 = accountsDAO.findByAgentId(PU15.getUser().getId());
                                                                                currAccounts15.setMyBonus(currAccounts15.getMyBonus() + P15.getBonus());
                                                                                accountsDAO.merge(currAccounts15);
                                                                                //TODO 修改所有订单为已使用
                                                                                //List<Order> orderList2 = orderDao.findOrderByUserId(PU15.getUserId());
                                                                                List<Order> orderList2 = orderDao.findOrderByUserId(PU15.getUser().getId());
                                                                                for (Order order1 : orderList2) {
                                                                                    order1.setIsUse("是");
                                                                                    orderDao.merge(order1);
                                                                                }
                                                                                Agent agent1 = agentHandler.get(PU15.getUser().getId());
                                                                                agent1.setFrequency("1");
                                                                                agentHandler.merge(agent1);
                                                                                //TODO 删除15层最后这个人
                                                                                pyramidUserHandler.removeActivity(PU15);
                                                                            }
                                                                        }else{
                                                                            System.out.println("结束了!");
                                                                        }
                                                                    }
                                                                }else{
                                                                    System.out.println("结束了!");
                                                                }
                                                            }
                                                        }else{
                                                            System.out.println("结束了!");
                                                        }
                                                    }
                                                }else{
                                                    System.out.println("结束了!");
                                                }
                                            }
                                        }else{
                                            System.out.println("结束了!");
                                        }
                                    }
                                }else{
                                    System.out.println("结束了!");
                                }
                            }
                        }else{
                            System.out.println("结束了!");
                        }
                    }else{
                        System.out.println("结束了!");
                    }
                }else{
                    System.out.println("结束了!");
                }
            }else{
                //TODO 不是待跳区的用户 全部结束 1-15层
                System.out.println("结束了!");
            }
        }
    }


    /**
     * 封装一下返代金券 上级20%  上上级10%
     * @param id
     * @param orderAmount
     */
    public void VoucherProfit(Integer id,Double orderAmount){
        Agent agent = agentHandler.get(id);
        //上级
        if(agent != null){
            Integer pid = agent.getParent().getId();
            if(pid != 3) {
                if(agent.getSign().equals("代理")){
                    Agent pAgent = agentHandler.get(pid);
                    if(pAgent.getId()!=3){
                        //上级账户
                        Accounts pAccounts = accountsDAO.findByAgentId(pAgent.getId());
                        Double yCount = pAccounts.getMyBonus();
                        Double oCount = orderAmount * 0.2 * 0.8;
                        Double xCount = yCount + oCount;
                        Double yShop = pAccounts.getShopVoucher();
                        Double oShop = orderAmount * 0.2 * 0.2;
                        Double xShop = yShop + oShop;
                        pAccounts.setMyBonus(xCount);
                        pAccounts.setShopVoucher(xShop);
                        accountsHandler.merge(pAccounts);

                        AccountsRecord ar = new AccountsRecord();
                        ar.setVersion(0);
                        ar.setAgent(pAgent);
                        ar.setCausedAgent(agent);
                        ar.setUpdateTime(new Date());
                        ar.setInfo("直推奖金奖励-"+"来自"+agent.getRealName());
                        ar.setAmount(oCount);
                        ar.setNowAmount(xCount);
                        ar.setAddSub(1);
                        ar.setAccountsType(AccountsType.MyBonus);
                        ar.setOrderIndex(0);
                        ar.setCanShow(true);
                        accountsRecordHandler.save(ar);
                        AccountsRecord ar1 = new AccountsRecord();
                        ar1.setVersion(0);
                        ar1.setAgent(pAgent);
                        ar1.setCausedAgent(agent);
                        ar1.setUpdateTime(new Date());
                        ar1.setInfo("直推购物券奖励-"+"来自"+agent.getRealName());
                        ar1.setAmount(oShop);
                        ar1.setNowAmount(xShop);
                        ar1.setAddSub(1);
                        ar1.setAccountsType(AccountsType.ShopVoucher);
                        ar1.setOrderIndex(0);
                        ar1.setCanShow(true);
                        accountsRecordHandler.save(ar1);
                        //上上级
                        Integer ppid = pAgent.getParent().getId();
                        if(ppid != 3){
                            Agent ppAgent = agentHandler.get(ppid);
                            if(ppAgent.getId()!=3){
                                if(ppAgent != null){
                                    //上上级账户
                                    Accounts ppAccounts = accountsDAO.findByAgentId(ppAgent.getId());
                                    Double ypCount = pAccounts.getMyBonus();
                                    Double opCount = orderAmount * 0.1 * 0.8;
                                    Double xpCount = ypCount + opCount;
                                    Double ypShop = pAccounts.getShopVoucher();
                                    Double opShop = orderAmount * 0.1 * 0.2;
                                    Double xpShop = ypShop + opShop;
                                    ppAccounts.setVoucherBalance(xpCount);
                                    ppAccounts.setShopVoucher(xpShop);
                                    accountsHandler.merge(ppAccounts);
                                    AccountsRecord ar2 = new AccountsRecord();
                                    ar2.setVersion(0);
                                    ar2.setAgent(ppAgent);
                                    ar2.setCausedAgent(agent);
                                    ar2.setUpdateTime(new Date());
                                    ar2.setInfo("间推奖金奖励-"+"来自"+agent.getRealName());
                                    ar2.setAmount(opCount);
                                    ar2.setNowAmount(xpCount);
                                    ar2.setAddSub(1);
                                    ar2.setAccountsType(AccountsType.MyBonus);
                                    ar2.setOrderIndex(0);
                                    ar2.setCanShow(true);
                                    accountsRecordHandler.save(ar2);
                                    AccountsRecord ar3 = new AccountsRecord();
                                    ar3.setVersion(0);
                                    ar3.setAgent(ppAgent);
                                    ar3.setCausedAgent(agent);
                                    ar3.setUpdateTime(new Date());
                                    ar3.setInfo("间推购物券奖励-"+"来自"+agent.getRealName());
                                    ar3.setAmount(opShop);
                                    ar3.setNowAmount(xpShop);
                                    ar3.setAddSub(1);
                                    ar3.setAccountsType(AccountsType.ShopVoucher);
                                    ar3.setOrderIndex(0);
                                    ar3.setCanShow(true);
                                    accountsRecordHandler.save(ar3);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 修改被挤人的位置，在获金，在记录，在改变位置。
     * @param pyramid
     */
    public void updatePUPositionAndBonusAndRecord(Pyramid pyramid){
        //TODO 获取当前层最后的这个用户并修改位置
        PyramidUser PU = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionASCLast(pyramid.getId());
        //PU.setPyramidId(pyramid.getId() + 1); //下一关下二层
        Pyramid pyramidPU = pyramidHandler.findById(pyramid.getId() + 1);
        PU.setPyramid(pyramidPU);
        //PU.setUserId(PU.getUserId()); //当前用户
        PU.setUser(PU.getUser());
        PU.setPosition("0");  //第一个位置
        PU.setUpdateTime(new Date()); //修改时间
        pyramidUserHandler.saveOrupdate(PU);

        //TODO 获取当前层的奖金并给到最后这个人
        //Accounts currAccounts1 = accountsDAO.findByAgentId(PU.getUserId());
        Accounts currAccounts1 = accountsDAO.findByAgentId(PU.getUser().getId());
        currAccounts1.setMyBonus(currAccounts1.getMyBonus() + pyramid.getBonus() * 0.8);
        currAccounts1.setShopVoucher(currAccounts1.getShopVoucher() + pyramid.getBonus() * 0.2);
        accountsDAO.merge(currAccounts1);

        //TODO 记录
        //Agent agent = agentHandler.get(PU.getUserId());
        Agent agent = agentHandler.get(PU.getUser().getId());
        AccountsRecord ar1 = new AccountsRecord();
        ar1.setVersion(0);
        ar1.setAgent(agent);
        ar1.setCausedAgent(agent);
        ar1.setUpdateTime(new Date());
        ar1.setInfo("奖金-来自网体");
        ar1.setAmount(pyramid.getBonus() * 0.8);
        ar1.setNowAmount(currAccounts1.getMyBonus());
        ar1.setAddSub(1);
        ar1.setAccountsType(AccountsType.MyBonus);
        ar1.setOrderIndex(0);
        ar1.setCanShow(true);
        accountsRecordHandler.save(ar1);

        AccountsRecord ar2 = new AccountsRecord();
        ar2.setVersion(0);
        ar2.setAgent(agent);
        ar2.setCausedAgent(agent);
        ar2.setUpdateTime(new Date());
        ar2.setInfo("购物券-来自网体");
        ar2.setAmount(pyramid.getBonus() * 0.2);
        ar2.setNowAmount(currAccounts1.getShopVoucher());
        ar2.setAddSub(1);
        ar2.setAccountsType(AccountsType.ShopVoucher);
        ar2.setOrderIndex(0);
        ar2.setCanShow(true);
        accountsRecordHandler.save(ar2);

        //TODO 当前层原来有的用户位置依次+1
        //TODO 获取当前层的人数
        List<PyramidUser> PUList = pyramidUserDAO.findPyramidUserByPyramidIdAndPositionDesc(pyramid.getId());
        //Integer puNumber9 = PUList.size();
        //TODO 判断PU中人数是否大于当前层限制人数
        //int indexSize = puNumber9;
        //if(indexSize >= 1){
            //TODO 循环修改位置，每个都+1
            for (int j = 0; j < PUList.size(); j++) {
                PyramidUser updatePU = PUList.get(j);
                String position = updatePU.getPosition();
                Integer index = Integer.valueOf(position) + 1;
                updatePU.setPosition(String.valueOf(index));
                pyramidUserHandler.saveOrupdate(updatePU);
            }
        //}
    }

    /**
     * 修改PU位置
     * @param list
     */
    public void updatePUPosition(List<PyramidUser> list){
        for (int j = 0; j < list.size(); j++) {
            PyramidUser pyramidUser = list.get(j);
            String position = pyramidUser.getPosition();
            Integer index = Integer.valueOf(position) + 1;
            pyramidUser.setPosition(String.valueOf(index));
            pyramidUserHandler.saveOrupdate(pyramidUser);
        }
    }


    @Override
    public List<Order> findOrders(SearchParameter<Order> p) {
        DetachedCriteria dc = DetachedCriteria.forClass(Order.class);
        Example example = Example.create(p.getEntity()).enableLike(MatchMode.ANYWHERE);
        dc.add(example);
        //下单人搜索
        if (p.getEntity().getUser() != null) {
            DetachedCriteria user = dc.createCriteria("user");
            Example example2 = Example.create(p.getEntity().getUser());
            user.add(example2);
//            addRestraction(user,"realName",p.getEntity().getUser().getRealName());
//            addRestraction(user,"agentCode",p.getEntity().getUser().getAgentCode());
        }
        //地址条件
        AddressClone addressClone = p.getEntity().getAddressClone();
        if (addressClone != null) {
            DetachedCriteria address = dc.createCriteria("addressClone");
            Example example1 = Example.create(p.getEntity().getAddressClone()).enableLike(MatchMode.ANYWHERE);
            address.add(example1);
//            addRestraction(address, "mobile", addressClone.getMobile());
//            addRestraction(address, "consignee", addressClone.getConsignee());
        }
        //时间搜索
        if (p.getStartTime() != null && p.getEndTime() != null) {
            dc.add(Restrictions.between("orderTime", p.getStartTimeByDate(), p.getEndTimeByDate()));
        }
        dc.addOrder(org.hibernate.criterion.Order.desc("id"));
        return orderDao.searchByPage(p, dc);
    }


    @Override
    public List<Order> findOrdersWithChildren(SearchParameter<Order> p) {
        DetachedCriteria dc = DetachedCriteria.forClass(Order.class);
        Example example = Example.create(p.getEntity()).enableLike(MatchMode.ANYWHERE);
        dc.add(example);
        //下单人搜索
        if (p.getEntity().getUser() != null) {
            DetachedCriteria user = dc.createCriteria("user");
//            Example example2 = Example.create(p.getEntity().getUser());
//            user.add(example2);
//            addRestraction(user,"realName",p.getEntity().getUser().getRealName());
//            addRestraction(user,"agentCode",p.getEntity().getUser().getAgentCode());
            //自己的或者用户的
            user.add(Restrictions.or(Restrictions.eq("id", p.getEntity().getUser().getId()), Restrictions.eq("parent.id", p.getEntity().getUser().getId())));
        }

        //时间搜索
        if (p.getStartTime() != null && p.getEndTime() != null) {
            dc.add(Restrictions.between("orderTime", p.getStartTimeByDate(), p.getEndTimeByDate()));
        }
        dc.addOrder(org.hibernate.criterion.Order.desc("id"));
        return orderDao.searchByPage(p, dc);
    }


    //提交订单
    private void commitOrder(Order order) {
        order.setUpdateTime(new Date());
        order.setOrderTime(new Date());
        order.setOrderNo(CommonUtil.createNo());
        order.setPaymentStatus(PaymentStatus.UNPAID);//设置成未支付
        order.setStatus(OrderStatus.NEW);//设置为新下单
    }

    private Set<OrderItem> bulidItems(Order order, ShopCart shopCart) {
        Set<OrderItem> items = new HashSet<>();
        shopCart.getItems().values().stream().forEach(p -> {
            //限制购买数量
            //validateActitivty(p.getGoods(), order.getUser(), p.getQuantity());
            OrderItem item = new OrderItem();
            item.setPmallOrder(order);

            item.setPrice(p.getGoods().getRetailPrice());
            item.setQuantity(p.getQuantity());
            List<GoodsStandard> goodsStandards = new ArrayList<>();
            //Set<GoodsStandard> standardSet = new HashSet<>();
            for (GoodsStandard gs : p.getGoodsStandards()) {
                GoodsStandard tem = goodsStandardHandler.get(gs.getId());
                goodsStandards.add(tem);
                //standardSet.add(tem);

            }
            item.setPmallGoods(p.getGoods());
            //PmallGoods pmallGoods = p.getGoods();
            //pmallGoods.setGoodsStandards(standardSet);
            //item.setPmallGoods(pmallGoods);
            item.setStandards(goodsStandards);
            if (!item.getPmallGoods().getCanAdvance()) {//存在一款不能代金券的
                order.setCanAdvance(false);//就都不能代金券
            }
            items.add(item);
        });
        return items;
    }


    /**
     * @param pmallGoods 购买产品
     * @param agent      购买人
     * @param quantity   购买数量
     */
    private void validateActitivty(PmallGoods pmallGoods, Agent agent, Integer quantity) {
        if (pmallGoods.getActivity() == false) return;
        List<OrderItem> orderItems = orderItemDao.findOrderItemByGoodsAndUserAndTime(pmallGoods.getId(), agent.getId(), pmallGoods.getStartTime());
        Integer sumQuantity = 0;
        for (OrderItem item : orderItems) {
            sumQuantity += item.getQuantity();
        }
        if (sumQuantity + quantity > pmallGoods.getLimitNumer()) {
            throw new ApplicationException("提交失败," + pmallGoods.getName() + "限购" + pmallGoods.getLimitNumer());
        }
    }

    //获取获得奖励明细
    private HashMap<Agent, Double> getAgentsWithVoucher(Order order) {
        HashMap<Agent, Double> maps = new HashMap<>();
        Agent agent = order.getUser();
        //首先找出能获得奖励的代理
        /*List<Agent> parents = new ArrayList<>();
        Agent parent = agent.getParent();
        while (parent != null && !parent.isMutedUser()) {
            if (agentHandler.canPmallReward(parent)) {
                parents.add(parent);//可以获得奖励的上级
            }
            parent = parent.getParent();
        }*/
        order.getItems().forEach(item -> {
            CommonUtil.putAll(maps, accountsHandler.rewardPmallVoucher(agent,item.getPmallGoods(),item.getQuantity()));
        });
        return maps;
    }



    //获得奖励
    private List<AccountsRecord> rewardVoucher(Order order) {
        List<AccountsRecord> accountsRecords = new ArrayList<>();
        StringBuffer sb = new StringBuffer();
        sb.append("利润--");
        sb.append(order.getUser().getRealName()).append("优惠商城购买:");
        order.getItems().forEach(p -> {
            if (p.getPmallGoods().getName().contains("避孕")) {
                sb.append("******");
            } else {
                sb.append(p.getPmallGoods().getName());
            }
            sb.append("X").append(p.getQuantity()).append("  ");
        });
        Map<Agent, Double> map = getAgentsWithVoucher(order);
        for (Agent agent : map.keySet()) {
            accountsRecords.add(accountsHandler.increaseAccountAndRecord(AccountsType.VOUCHER, agent, order.getUser(), map.get(agent), sb.toString()));
        }
        return accountsRecords;
    }


    /**
     * 减少产品库存
     *
     * @param order
     */
    private void deductMallGoodsAccount(Order order) {
        order.getItems().forEach(p -> {
            //减少总库存
            mallGoodsHandler.deductMallGoodsAccount(p.getPmallGoods(), p.getQuantity());
            //减少单品库存
//            p.getStandards().forEach(st -> {
//                st.deductCurrentStock(p.getQuantity());
//            });
        });
    }


    //发货
    @Override
    @Transactional
    public void delivery(Integer id, String logistics, String logisticsCode, String operate) {
        Order order = get(id);
        if (hasDelivery(order)) {
            throw new ApplicationException("订单已经发货");
        }
        order.setLogisticsCode(logisticsCode);
        order.setLogistics(logistics);
        order.setShippingOperator(operate);
        order.setShippingTime(new Date());//发货时间
        order.setStatus(OrderStatus.SHIPPED);//已经发货
        merge(order);
        //通知
        noticeHandler.noticeOrder(order);
    }


    @Override
    public List<Order> findAllOrders(SearchParameter<Order> p) {

        return orderDao.findAllOrders(p);
    }

    @Override
    public List<Order> findNewOrders(Integer limit) {

        return orderDao.findNewOrders( limit);
    }

    //获取所有没有发货的订单总数
    @Override
    public List<Object[]> getOrdersItemCount(Integer limit) {
        return orderDao.getOrdersItemCount( limit);
    }

    private OrderDao orderDao;

    public OrderDao getOrderDao() {
        return orderDao;
    }

    @Autowired
    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
        super.setBaseDao(orderDao);
    }

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AccountsHandler accountsHandler;

    @Autowired
    private NoticeHandler noticeHandler;

    @Autowired
    private AgentHandler agentHandler;

    @Autowired
    private MallGoodsHandler mallGoodsHandler;

    @Autowired
    private GoodsStandardHandler goodsStandardHandler;

    @Autowired
    private WxConfigFactory wxConfigFactory;

    @Autowired
    private OrderItemDao orderItemDao;



    @Autowired
    private PayHandler payHandler;

    @Autowired
    private AccountsRecordHandler accountsRecordHandler;

    private Logger LOG = LoggerFactory.getLogger(this.getClass());
}
